// Copyright (c) 2005  INRIA Sophia-Antipolis (France).
// All rights reserved.
//
// This file is part of cgal-python; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public License as
// published by the Free Software Foundation; version 2.1 of the License.
// See the file LICENSE.LGPL distributed with cgal-python.
//
// Licensees holding a valid commercial license may use this file in
// accordance with the commercial license agreement provided with the software.
//
// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
//
// $Id: Py_global_functions_3.cpp 176 2007-11-07 15:44:39Z spion $
// $URL: svn+ssh://scm.gforge.inria.fr/svn/cgal-python/trunk/cgal-python/bindings/Kernel/Py_global_functions_3.cpp $
//
// Author(s)     : Naceur Meskini
//=========================================================================


// include ====================================================================
#include <CGAL/basic.h>
#include <include/Kernels.h>
#include <CGAL/Kernel/global_functions_3.h>
// Boost include ==============================================================
#include <boost/python.hpp>
#include <boost/cstdint.hpp>

template <class kernel > 
void Py_global_functions_3()
{
	// Using =======================================================================
	using namespace boost::python;

	typedef typename kernel::Point_3 							Point_3;
	typedef typename kernel::Aff_transformation_3 				Aff_transformation_3;
	typedef typename kernel::Segment_3 							Segment_3;
 	typedef typename kernel::Vector_3 							Vector_3;
 	typedef typename kernel::Direction_3 						Direction_3;
 	typedef typename kernel::Line_3 						    Line_3;
  	typedef typename kernel::Ray_3 						        Ray_3;
 	typedef typename kernel::Triangle_3 						Triangle_3;
 	typedef typename kernel::Plane_3 							Plane_3;
 	typedef typename kernel::Iso_cuboid_3 						Iso_cuboid_3;
 	typedef typename kernel::Sphere_3 							Sphere_3;
 	typedef typename kernel::Tetrahedron_3 						Tetrahedron_3;


	typedef typename kernel::FT FT;
	using namespace CGAL;

    def("compare_lexicographically_xyz", (Comparison_result (*)(const Point_3 &,const Point_3 &))&compare_lexicographically_xyz);
    def("coplanar_orientation", (Orientation (*)(const Point_3&, const Point_3&, const Point_3&, const Point_3&))&coplanar_orientation);
    def("coplanar_orientation", (Orientation (*)(const Point_3&, const Point_3&, const Point_3&))&coplanar_orientation);
    def("coplanar_side_of_bounded_circle", (Bounded_side (*)(const Point_3&,const Point_3&,const Point_3&,const Point_3 &))&coplanar_side_of_bounded_circle);
//    def("cross_product", (Vector_3 (*)(const Vector_3&, const Vector_3&))&cross_product);
    def("has_larger_signed_distance_to_plane", (bool (*)(const Point_3&, const Point_3&, const Point_3&, const Point_3&, const Point_3&))&has_larger_signed_distance_to_plane);
    def("has_larger_signed_distance_to_plane", (bool (*)(const Plane_3&, const Point_3&, const Point_3&))&has_larger_signed_distance_to_plane);
    def("has_smaller_distance_to_point", (bool (*)(const Point_3 &,const Point_3 &,const Point_3 &))&has_smaller_distance_to_point);
    def("centroid", (Point_3 (*)(const Point_3&, const Point_3&, const Point_3&))&centroid);
    def("centroid", (Point_3 (*)(const Point_3&, const Point_3&, const Point_3&, const Point_3&))&centroid);
    def("centroid", (Point_3 (*)(const Triangle_3&))&centroid);
    def("centroid", (Point_3 (*)(const Tetrahedron_3&))&centroid);
	def("circumcenter", (Point_3 (*)(const Point_3&, const Point_3&, const Point_3&, const Point_3&))&circumcenter);
    def("circumcenter", (Point_3 (*)(const Point_3&, const Point_3&, const Point_3&))&circumcenter);
  //  def("circumcenter", (Point_3 (*)(const Tetrahedron_3&))&circumcenter);
//    def("circumcenter", (Point_3 (*)(const Triangle_3&))&circumcenter);
    def("collinear_are_ordered_along_line",(bool (*)(const Point_3 &,const Point_3 &,const Point_3 &))&collinear_are_ordered_along_line);
    def("collinear", (bool (*)(const Point_3 &,const Point_3 &,const Point_3 &))&collinear);

	//def("squared_radius", (FT (*)(const Point_3&, const Point_3&, const Point_3&))&squared_radius);
 //  def("squared_radius", (FT (*)(const Point_3&, const Point_3&, const Point_3&, const Point_3&))&squared_radius);

    def("lexicographically_xyz_smaller",(bool (*)(const Point_3 &, const Point_3 &))&lexicographically_xyz_smaller);
    def("less_z", (bool (*)(const Point_3 &, const Point_3 &))&less_z);
    def("midpoint",(Point_3 (*)(const Point_3 &, const Point_3 &))&midpoint); //midpoint(Point_3(),Point_3());
    def("lexicographically_xyz_smaller_or_equal",(bool (*)(const Point_3 &, const Point_3 &)) &lexicographically_xyz_smaller_or_equal);
    def("min_vertex", (Point_3 (*)(const Iso_cuboid_3 &))&min_vertex); min_vertex(Iso_cuboid_3());
    def("max_vertex", (Point_3 (*)(const Iso_cuboid_3 &))&max_vertex); max_vertex(Iso_cuboid_3());
    def("orientation", (Orientation (*)(const Vector_3&, const Vector_3&, const Vector_3&))&orientation);
    def("orientation", (Orientation (*)(const Point_3&, const Point_3&, const Point_3&, const Point_3&))&orientation);
    def("less_y", (bool (*)(const Point_3 &, const Point_3 &))&less_y);
    def("less_x", (bool (*)(const Point_3 &, const Point_3 &))&less_x);
    def("x_equal",(bool (*)(const Point_3 &, const Point_3 &))&x_equal);
    def("volume", &volume<kernel>);
    def("z_equal", (bool (*)(const Point_3 &, const Point_3 &))&z_equal);
    def("y_equal", (bool (*)(const Point_3 &, const Point_3 &))&y_equal);
    def("compare_distance_to_point", (Comparison_result (*)(const Point_3 &, const Point_3 &,const Point_3 &))&compare_distance_to_point);
    def("collinear_are_strictly_ordered_along_line",(bool (*)(const Point_3 &, const Point_3 &,const Point_3 &)) &collinear_are_strictly_ordered_along_line);
    def("coplanar", (bool (*)(const Point_3 &, const Point_3 &,const Point_3 &, const Point_3 &))&coplanar);
    def("compare_xyz", (Comparison_result (*)(const Point_3 &,const Point_3 &))&compare_xyz);
    def("compare_z", (Comparison_result (*)(const Point_3 &,const Point_3 &))&compare_z);
    def("compare_y", (Comparison_result (*)(const Point_3 &,const Point_3 &))&compare_y);
    def("compare_x", (Comparison_result (*)(const Point_3 &,const Point_3 &))&compare_x);
    def("compare_signed_distance_to_plane", (Comparison_result (*)(const Point_3&, const Point_3&, const Point_3&, const Point_3&, const Point_3&))&compare_signed_distance_to_plane);
    def("compare_signed_distance_to_plane", (Comparison_result (*)(const Plane_3&, const Point_3&, const Point_3&))&compare_signed_distance_to_plane);
    def("are_negative_oriented", (bool (*)(const Point_3 &,const Point_3 &,const Point_3 &,const Point_3 &))&are_negative_oriented);
    def("are_ordered_along_line", (bool (*)(const Point_3 &,const Point_3 &,const Point_3 &))&are_ordered_along_line);
    def("angle", (Angle (*)(const Point_3 &,const Point_3 &,const Point_3 &))&angle);
    
//	def("bisector", (Plane_3 (*)(const Point_3&, const Point_3&))&bisector);
//    def("bisector", (Plane_3 (*)(const Plane_3&, const Plane_3&))&bisector);

    def("are_positive_oriented", (bool (*)(const Point_3 &,const Point_3 &,const Point_3 &,const Point_3 &))&are_positive_oriented);
    def("are_strictly_ordered_along_line", (bool (*)(const Point_3 &,const Point_3 &,const Point_3 &))&are_strictly_ordered_along_line);
    def("has_larger_distance_to_point", (bool (*)(const Point_3 &,const Point_3 &,const Point_3 &))&has_larger_distance_to_point);
    def("side_of_bounded_sphere", (Bounded_side (*)(const Point_3&, const Point_3&, const Point_3&, const Point_3&, const Point_3&))&side_of_bounded_sphere);
    def("side_of_bounded_sphere", (Bounded_side (*)(const Point_3&, const Point_3&, const Point_3&))&side_of_bounded_sphere);
    def("side_of_bounded_sphere", (Bounded_side (*)(const Point_3&, const Point_3&, const Point_3&, const Point_3&))&side_of_bounded_sphere);
    def("side_of_oriented_sphere", (Oriented_side (*)(const Point_3 &,const Point_3 &,const Point_3 &,const Point_3 &,const Point_3 &))&side_of_oriented_sphere);

    //def("squared_radius", (FT (*)(const Point_3&, const Point_3&, const Point_3&))&squared_radius);
    //def("squared_radius", (FT (*)(const Point_3&, const Point_3&, const Point_3&, const Point_3&))&squared_radius);
    //def("squared_radius", (FT (*)(const Point_3&, const Point_3&))&squared_radius);
    //def("squared_area", (FT (*)(const Point_3&, const Point_3&, const Point_3&))&squared_area);

//    def("orthogonal_vector", (Vector_3 (*)(const Point_3&, const Point_3&, const Point_3&))&orthogonal_vector);
//    def("orthogonal_vector", (Vector_3 (*)(const Plane_3&))&orthogonal_vector);
}

void export_global_functions_3()
{
	Py_global_functions_3<K>();
}
